#!/bin/bash

# MCSL compiling script.  Automates steps for converting a mcsl source file
# into an executable, or an in between state.

Usage () { cat; } <<doc
Usage: $CMD [options] filename
mcsl is a frontend to mcslc and mcsli, respectively the Monte Carlo Simulation
Language's compiler and interpreter.  By default, it will compile the input
file into an executable.  Use the options to change its behaviour.
Options:
    -C <file>	Use <file> as mcsl compiler
    -h		Print usage and exit
    -o <file>	Place output into <file>
    -t		Only translate to ocaml, don't compile
doc

Error () {
    rm -f $RMLIST &>/dev/null
    echo "$CMD: ${1:-"error"}" >&2
    exit ${2:-1}
}

# Get compiler command and directory
CMD=${0##*/}
DIR=${0%/*}

# Defaults
MCSLC="$DIR/../src/mcslc"
MCSLI="$DIR/../src/mcsli"
MCLIB="$DIR/../lib"
COMPILE=true
LIBS="libmcsl.cma"
RMLIST=""

# Minimal check
if [[ -z $1 ]] ;
then Error "no input files";
fi

# Scan arguments
while [[ -n $1 ]] ;
do
    case $1 in
    # Use an alternative compiler executable
	-C)
	if [[ -z $2 ]] ;
	then Error "no file for -C option"
	fi
	MCSLC=$2
	shift 2
	;;

    # Print usage and exit
	-h)
	Usage
	exit 0
	;;

    # Set an output file
	-o)
	if [[ -z $2 ]] ;
	then Error "no file for -o option"
	fi
	OUT=$2
	shift 2
	;;

    # No compilation
	-t)
	COMPILE=
	shift
	;;

    # Get input file and check for existance and extension
	*)
	if [[ -n $SRC ]] ;
	then Error "too many input files";
	fi

	SRC=$1
	if [[ ! -r $SRC ]] ;
	then Error "can't read file: $SRC";
	fi

	BASE=${1%.*}
	BASE=${BASE##*/}
	EXT=${1##*.}
	case $EXT in
	    "mcsl")
	    ;;
	    *)
	    Error "unknown filetype: $SRC"
	    ;;
	esac
	shift
	;;
    esac;
done

# Translate mcsl to ml
if [[ ! -x $MCSLC ]] ;
then Error "can't execute compiler"
fi
RMLIST="$RMLIST $BASE.ml"
$MCSLC $SRC
if [[ $? -ne 0 ]] ;
then
    Error
fi
if [[ ! $COMPILE ]] ;
then
    if [[ -n $OUT ]] ;
    then mv $BASE.ml $OUT
    fi
    exit 0
fi

# Compile ml to executable
OCAMLC=$(which ocamlc)
if [[ $? -ne 0 ]] ;
then Error "can't find ocamlc"
fi
$OCAMLC -o ${OUT:=$BASE} -I $MCLIB $LIBS $BASE.ml
if [[ $? -ne 0 ]] ;
then Error
fi
RMLIST="$RMLIST $BASE.cmo $BASE.cmi"
rm -f $RMLIST &> /dev/null
./$OUT
